home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / gfx_card / rblanke2.lha / RBlankers / rcurves.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-13  |  21.3 KB  |  787 lines

  1. /*
  2.  * RCurves
  3.  *
  4.  * A screen blanker for the Retina graphics card.
  5.  * By Michael Heinz, 29 March, 1994
  6.  *
  7.  * This software is FREEWARE.  It may be freely distributed for non-commercial use.        
  8.  * All rights are reserved by the author.                 
  9.  *
  10.  */
  11.  
  12. #include <exec/memory.h>
  13. #include <exec/ports.h>
  14. #include <exec/execbase.h>
  15. #include <graphics/displayinfo.h>
  16. #include <intuition/intuitionbase.h>
  17. #include <intuition/gadgetclass.h>
  18. #include <libraries/commodities.h>
  19. #include <libraries/gadtools.h>
  20. #include <dos/dosextens.h>
  21. #include <dos/dostags.h>
  22. #include <utility/tagitem.h>
  23.  
  24. #include <clib/alib_protos.h>
  25. #include <clib/commodities_protos.h>
  26. #include <clib/dos_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/gadtools_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/intuition_protos.h>
  31. #include <clib/macros.h>
  32. #include <clib/retina_protos.h>
  33. #include <libraries/retina.h>
  34.  
  35. #include <string.h>
  36. #include <math.h>
  37. #include <stdlib.h>
  38.  
  39. #include <pragmas/commodities_pragmas.h>
  40. #include <pragmas/dos_pragmas.h>
  41. #include <pragmas/exec_pragmas.h>
  42. #include <pragmas/gadtools_pragmas.h>
  43. #include <pragmas/graphics_pragmas.h>
  44. #include <pragmas/intuition_pragmas.h>
  45. #include <pragmas/retina_pragmas.h>
  46. #include "blanker.h"
  47.  
  48. UBYTE *VersionString = "$VER: $Id: rcurves.c 2.6 1994/07/12 17:13:22 mheinz Exp mheinz $";
  49.  
  50. unsigned char color_table[] =
  51. {
  52.     0, 0, 0, 0, 0, 70, 0, 0, 76, 0, 0, 82, 0, 0, 88, 0, 0, 94,
  53.     0, 0, 100, 0, 0, 106, 0, 0, 112, 0, 0, 118, 0, 0, 124, 0, 0, 130,
  54.     0, 0, 136, 0, 0, 142, 0, 0, 148, 0, 0, 154, 0, 0, 160, 0, 0, 166,
  55.     0, 0, 172, 0, 0, 178, 0, 0, 184, 0, 0, 190, 0, 0, 196, 0, 0, 202,
  56.     0, 0, 208, 0, 0, 214, 0, 0, 220, 0, 0, 226, 0, 0, 232, 0, 0, 238,
  57.     0, 0, 244, 0, 0, 250, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255,
  58. 16, 0, 255, 20, 0, 255, 24, 0, 255, 28, 0, 255, 32, 0, 255, 36, 0, 255,
  59. 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0, 255, 56, 0, 255, 60, 0, 255,
  60. 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0, 255, 80, 0, 255, 84, 0, 255,
  61.     88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0, 255, 104, 0, 255, 108, 0, 255,
  62.     112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0, 255, 128, 0, 255, 132, 0, 255,
  63.     136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0, 255, 152, 0, 255, 156, 0, 255,
  64.     160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0, 255, 180, 0, 255,
  65.     184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0, 255, 204, 0, 255,
  66.     208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0, 255, 228, 0, 255,
  67.     232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0, 255, 252, 0, 255,
  68.     255, 0, 252, 255, 0, 248, 255, 0, 244, 255, 0, 240, 255, 0, 236, 255, 0, 232,
  69.     255, 0, 228, 255, 0, 224, 255, 0, 220, 255, 0, 216, 255, 0, 212, 255, 0, 208,
  70.     255, 0, 204, 255, 0, 200, 255, 0, 196, 255, 0, 192, 255, 0, 188, 255, 0, 184,
  71.     255, 0, 180, 255, 0, 176, 255, 0, 172, 255, 0, 168, 255, 0, 164, 255, 0, 160,
  72.     255, 0, 156, 255, 0, 152, 255, 0, 148, 255, 0, 144, 255, 0, 140, 255, 0, 136,
  73.     255, 0, 132, 255, 0, 128, 255, 0, 124, 255, 0, 120, 255, 0, 116, 255, 0, 112,
  74.     255, 0, 108, 255, 0, 104, 255, 0, 100, 255, 0, 96, 255, 0, 92, 255, 0, 88,
  75.     255, 0, 84, 255, 0, 80, 255, 0, 76, 255, 0, 72, 255, 0, 68, 255, 0, 64, 255, 0, 60,
  76.     255, 0, 56, 255, 0, 52, 255, 0, 48, 255, 0, 44, 255, 0, 40, 255, 0, 36, 255, 0, 32,
  77.     255, 0, 28, 255, 0, 24, 255, 0, 20, 255, 0, 16, 255, 0, 12, 255, 0, 8, 255, 0, 4,
  78.     255, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 16, 0, 255, 20, 0, 255, 24, 0,
  79.     255, 28, 0, 255, 32, 0, 255, 36, 0, 255, 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0,
  80. 255, 56, 0, 255, 60, 0, 255, 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0,
  81.     255, 80, 0, 255, 84, 0, 255, 88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0,
  82.     255, 104, 0, 255, 108, 0, 255, 112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0,
  83.     255, 128, 0, 255, 132, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0,
  84.     255, 152, 0, 255, 156, 0, 255, 160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0,
  85.     255, 180, 0, 255, 184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0,
  86.     255, 204, 0, 255, 208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0,
  87.     255, 228, 0, 255, 232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0,
  88.     255, 252, 0, 255, 255, 0, 255, 255, 8, 255, 255, 16, 255, 255, 24, 255, 255, 32,
  89.     255, 255, 40, 255, 255, 48, 255, 255, 56, 255, 255, 64, 255, 255, 72, 255, 255, 80,
  90.     255, 255, 88, 255, 255, 96, 255, 255, 104, 255, 255, 112, 255, 255, 120, 255, 255, 128,
  91.     255, 255, 136, 255, 255, 144, 255, 255, 152, 255, 255, 160, 255, 255, 168, 255, 255, 176,
  92.     255, 255, 184, 255, 255, 192, 255, 255, 200, 255, 255, 208, 255, 255, 216, 255, 255, 224,
  93.     255, 255, 232, 255, 255, 240, 255, 255, 248, 255, 255, 255,
  94. };
  95.  
  96. /*
  97.  * A handy request structure for reporting that we've up and died.
  98.  */
  99. struct EasyStruct quitreq =
  100. {
  101.     sizeof(struct EasyStruct),
  102.     0,
  103.     "RCurves",
  104.     "RCurves has suffered an untimely demise\ndue to: %s",
  105.     "OK|OK"
  106. };
  107.  
  108. /*
  109.  * Commodity Broker
  110.  */
  111. struct NewBroker NewBroker =
  112. {NB_VERSION, "RCurves ", NULL,
  113.  "Silly Rabbit, Qix are for Qids!", NBU_NOTIFY | NBU_UNIQUE, COF_SHOW_HIDE,
  114.  0, NULL, 0};
  115.  
  116. #define MAX_SPEED     20L
  117. #define MAX_LINES     100L
  118. #define LINE_BUF      512L
  119.  
  120. #define MIN_LINES      10L
  121. #define DEF_LINES     20L
  122. #define DEF_SPEED     10L
  123.  
  124. #define DELTA_V          10L
  125.  
  126. LONG NumLines, Speed;
  127.  
  128. typedef struct {
  129.     unsigned char color;
  130.     int cur_point;
  131.     int last_point;
  132.     int max_points;
  133.     int tic, speed;
  134.     double av, bv, cv, dv;
  135.     double point_list[LINE_BUF][4];
  136. } PList;
  137.  
  138. PList plist;
  139.  
  140. /*
  141.  * Definitions for our configuration window
  142.  */
  143.  
  144. struct NewWindow NewBlankerWindow =
  145. {
  146.     80, 16, 0, 0, 0, 1,
  147.     IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
  148.     IDCMP_GADGETUP | IDCMP_VANILLAKEY | SLIDERIDCMP | LISTVIEWIDCMP,
  149.     WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH,
  150.     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
  151.     WBENCHSCREEN
  152. };
  153.  
  154. struct Window *BlankerWindow;
  155.  
  156. #define GID_HIDE          1
  157. #define GID_BLANK         2
  158. #define GID_QUIT          3
  159. #define GID_TIMEOUT       4
  160. #define GID_CLIENT        5
  161. #define GID_LINES          6
  162. #define GID_SPEED         7
  163.  
  164. #define NUM_GADS         7
  165.  
  166. struct VisualInfo *BlankerVisualInfo;
  167. struct Gadget *BlankerGadgets;
  168. struct TextAttr BlankerAttr =
  169. {"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT};
  170.  
  171. struct NewGadget NewBlankerGadgets[NUM_GADS] =
  172. {16, 101, 48, 12, "_Hide", &BlankerAttr, GID_HIDE, PLACETEXT_IN, NULL, NULL,
  173.  80, 101, 48, 12, "_Blank", &BlankerAttr, GID_BLANK, PLACETEXT_IN, NULL, NULL,
  174.  144, 101, 48, 12, "_Quit", &BlankerAttr, GID_QUIT, PLACETEXT_IN, NULL, NULL,
  175.  136, 5, 66, 12, "Timeout", &BlankerAttr, GID_TIMEOUT, PLACETEXT_LEFT, NULL, NULL,
  176.  136, 21, 66, 12, "Client Timeout", &BlankerAttr, GID_CLIENT, PLACETEXT_LEFT, NULL, NULL,
  177.  136, 53, 66, 12, "Speed    ", &BlankerAttr, GID_SPEED, PLACETEXT_LEFT, NULL, NULL,
  178.  136, 69, 66, 12, "Lines    ", &BlankerAttr, GID_LINES, PLACETEXT_LEFT, NULL, NULL,
  179. };
  180.  
  181. UBYTE BlankerGadgetKinds[NUM_GADS] =
  182. {
  183.     BUTTON_KIND, BUTTON_KIND, BUTTON_KIND, INTEGER_KIND, INTEGER_KIND, SLIDER_KIND,
  184.     SLIDER_KIND,
  185. };
  186.  
  187. struct TagItem ButtonGadgetTags[] =
  188. {GT_Underscore, (ULONG) '_', TAG_DONE, 0L};
  189.  
  190. struct TagItem TimeGadgetTags[] =
  191. {GTIN_Number, 0L, GTIN_MaxChars, 4L, TAG_DONE, 0L};
  192.  
  193. struct TagItem ClientGadgetTags[] =
  194. {GTIN_Number, 0L, GTIN_MaxChars, 2L, TAG_DONE, 0L};
  195.  
  196. struct TagItem SpeedGadgetTags[] =
  197. {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_SPEED, GTSL_LevelFormat, 0L,
  198.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
  199.  TAG_DONE, 0L};
  200.  
  201. struct TagItem LinesGadgetTags[] =
  202. {GTSL_Level, 0L, GTSL_Min, MIN_LINES, GTSL_Max, MAX_LINES, GTSL_LevelFormat, 0L,
  203.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 3L, GA_RELVERIFY, TRUE,
  204.  TAG_DONE, 0L};
  205.  
  206. struct TagItem *BlankerGadgetTagLists[NUM_GADS] =
  207. {
  208.     &ButtonGadgetTags[0],
  209.     &ButtonGadgetTags[0],
  210.     &ButtonGadgetTags[0],
  211.     &TimeGadgetTags[0],
  212.     &ClientGadgetTags[0],
  213.     &SpeedGadgetTags[0],
  214.     &LinesGadgetTags[0],
  215. };
  216.  
  217. void
  218. CloseBlankerWindow(void)
  219. {
  220.     if (BlankerWindow) {
  221.         /*
  222.          * We save the current position of the window
  223.          * so it will re-open in the same place, later.
  224.          */
  225.         NewBlankerWindow.LeftEdge = BlankerWindow->LeftEdge;
  226.         NewBlankerWindow.TopEdge = BlankerWindow->TopEdge;
  227.  
  228.         RemTool(BlankerGadgets);
  229.         RemTool(BlankerVisualInfo);
  230.         RemTool(BlankerWindow);
  231.         BlankerWindow = NULL;
  232.     }
  233. }
  234.  
  235. void
  236. OpenBlankerWindow(void)
  237. {
  238.     struct Gadget *Ptr;
  239.     UWORD Index;
  240.     static char Title[80];
  241.  
  242.     if (BlankerWindow == NULL) {
  243.         strcpy(Title, "RCurves = <");
  244.         strcat(Title, PopKey);
  245.         strcat(Title, ">");
  246.  
  247.         if (BlankerWindow = OpenWindowTags(&NewBlankerWindow, WA_Title, Title,
  248.                                    WA_AutoAdjust, TRUE, WA_InnerWidth,
  249.                                 212, WA_InnerHeight, 118, TAG_DONE)) {
  250.  
  251.             AddTool(BlankerWindow, CloseWindow, NULL, "Could not open the window.");
  252.  
  253.             if ((BlankerVisualInfo = GetVisualInfo(BlankerWindow->WScreen, TAG_DONE))
  254.                 == NULL) {
  255.                 RemTool(BlankerWindow);
  256.                 return;
  257.             }
  258.             AddTool(BlankerVisualInfo, FreeVisualInfo, 0L,
  259.                     "Couldn't get visual data.");
  260.  
  261.             BlankerGadgets = NULL;
  262.             if ((Ptr = CreateContext(&BlankerGadgets)) == NULL) {
  263.                 RemTool(BlankerVisualInfo);
  264.                 RemTool(BlankerWindow);
  265.                 return;
  266.             }
  267.             AddTool(Ptr, FreeGadgets, 0L, "Couldn't allocate the gadgets.");
  268.  
  269.             /*
  270.              * Here we re-load the gadgets with the current settings. 
  271.              */
  272.             TimeGadgetTags[0].ti_Data = (ULONG) TimeOut;
  273.             ClientGadgetTags[0].ti_Data = (ULONG) ClientTimeOut;
  274.             SpeedGadgetTags[0].ti_Data = (ULONG) Speed;
  275.             SpeedGadgetTags[3].ti_Data = (ULONG) "%2ld";
  276.             LinesGadgetTags[0].ti_Data = (ULONG) NumLines;
  277.             LinesGadgetTags[3].ti_Data = (ULONG) "%3ld";
  278.  
  279.             for (Index = 0L; Index < NUM_GADS; Index++) {
  280.                 NewBlankerGadgets[Index].ng_TopEdge += BlankerWindow->BorderTop;
  281.  
  282.                 NewBlankerGadgets[Index].ng_VisualInfo = BlankerVisualInfo;
  283.                 Ptr = CreateGadgetA((ULONG) BlankerGadgetKinds[Index], Ptr,
  284.                                     &NewBlankerGadgets[Index],
  285.                                     BlankerGadgetTagLists[Index]);
  286.                 if (Ptr == NULL) {
  287.                     CloseBlankerWindow();
  288.                     return;
  289.                 }
  290.                 NewBlankerGadgets[Index].ng_TopEdge -= BlankerWindow->BorderTop;
  291.             }
  292.  
  293.             AddGList(BlankerWindow, BlankerGadgets, 0L, -1L, NULL);
  294.             RefreshGadgets(BlankerGadgets, BlankerWindow, NULL);
  295.             GT_RefreshWindow(BlankerWindow, NULL);
  296.         }
  297.     }
  298.     ScreenToFront(BlankerWindow->WScreen);
  299.     WindowToFront(BlankerWindow);
  300.     ActivateWindow(BlankerWindow);
  301. }
  302.  
  303. /*
  304.  * Functions for Creating/Drawing/Removing the Lines
  305.  */
  306.  
  307. WORD __inline
  308. Insure1(WORD val)
  309. {
  310.     return (WORD)((val == 0) ? (WORD)1 : val);
  311. }
  312.  
  313. /*
  314.  * Create the list of points.
  315.  */
  316. void *__regargs
  317. CreateLines(struct RetinaScreen *Screen,
  318.             LONG NumLines, LONG Speed)
  319. {
  320.     int i;
  321.  
  322.     if (!Screen)
  323.         return NULL;
  324.  
  325.     for (i = 0; i < LINE_BUF; i++) {
  326.         plist.point_list[i][0] = -1;
  327.         plist.point_list[i][1] = -1;
  328.         plist.point_list[i][2] = -1;
  329.         plist.point_list[i][3] = -1;
  330.     }
  331.  
  332.     plist.color = 1;
  333.     plist.max_points = NumLines;
  334.     plist.speed = Speed;
  335.     plist.last_point = 0;
  336.     plist.cur_point = NumLines;
  337.     plist.point_list[NumLines][0] = drand48() * 4.0;
  338.     plist.point_list[NumLines][1] = drand48() * 4.0;
  339.     plist.point_list[NumLines][2] = drand48() * 4.0;
  340.     plist.point_list[NumLines][3] = drand48() * 4.0;
  341.     plist.av = drand48() + 0.01;
  342.     plist.bv = drand48() + 0.01;
  343.     plist.cv = drand48() + 0.01;
  344.     plist.dv = drand48() + 0.01;
  345.  
  346.     return (void *)&plist;
  347. }
  348.  
  349. int __inline __regargs
  350. Bound(double l, double *m, double u)
  351. {
  352.     if (*m < l) {
  353.         *m = l;
  354.         return 1;
  355.     }
  356.     if (*m >= u) {
  357.         *m = u - 1;
  358.         return 1;
  359.     }
  360.     return 0;
  361. }
  362.  
  363. void __inline
  364. Draw_Image(struct RetinaScreen *rs, double a, double b, double c, double d)
  365. {
  366.     double f, x, y, z, xinc, yinc, xmid, ymid;
  367.     int xi, yi, xp, yp;
  368.  
  369.     xp = -1;
  370.     yp = -1;
  371.  
  372.     xinc = (double)rs->rs_Width / 8.0;
  373.     yinc = (double)rs->rs_Height / 6.0;
  374.     xmid = (double)rs->rs_Width / 2.0;
  375.     ymid = (double)rs->rs_Height / 2.0;
  376.  
  377.     for (f = 0; f < PI2; f += FINC) {
  378.         z = a * sin(f * c) + b * cos(f * d);
  379.         x = z * cos(f);
  380.         y = z * sin(f);
  381.  
  382.         xi = (int)(x * xinc + xmid);
  383.         yi = (int)(y * yinc + ymid);
  384.  
  385.         if ((xi >= 0) && (xi < rs->rs_Width) && (yi >= 0) && (yi < rs->rs_Height)) {
  386.             if (xp < 0) {
  387.                 Retina_Line(rs, xi, yi, xi, yi);
  388.             } else {
  389.                 Retina_Line(rs, xi, yi, xp, yp);
  390.             }
  391.             xp = xi;
  392.             yp = yi;
  393.         } else {
  394.             xp = -1;
  395.         }
  396.     }
  397. }
  398.  
  399. /*
  400.  * move the Lines and redraw them 
  401.  */
  402. void __regargs
  403. DrawLines(void *xplist, struct RetinaScreen *rs)
  404. {
  405.     double *pl;
  406.     PList *plist = xplist;
  407.  
  408.     /*
  409.      * If we don't have a screen, don't draw on it! (duh.) 
  410.      */
  411.     if (!rs)
  412.         return;
  413.  
  414.     if (plist->tic) {
  415.         plist->tic--;
  416.         return;
  417.     }
  418.     plist->tic = Insure1(MAX_SPEED - plist->speed);
  419.  
  420.     pl = plist->point_list[plist->cur_point];
  421.  
  422.     Retina_SetAPen(rs, plist->color);
  423.     plist->color++;
  424.  
  425.     Draw_Image(rs, pl[0], pl[1], pl[2], pl[3]);
  426.  
  427.     plist->cur_point = (plist->cur_point + 1) % LINE_BUF;
  428.  
  429.     plist->point_list[plist->cur_point][0] = pl[0] + plist->av;
  430.     plist->point_list[plist->cur_point][1] = pl[1] + plist->bv;
  431.     plist->point_list[plist->cur_point][2] = pl[2] + plist->cv;
  432.     plist->point_list[plist->cur_point][3] = pl[3] + plist->dv;
  433.  
  434.     if (Bound(0.0, &plist->point_list[plist->cur_point][0], 4.0)) {
  435.         if (plist->av > 0) {
  436.             plist->av = -drand48() / 16.0 - 0.01;
  437.         } else {
  438.             plist->av = drand48() / 16.0 + 0.01;
  439.         }
  440.     }
  441.     if (Bound(0.0, &plist->point_list[plist->cur_point][1], 4.0)) {
  442.         if (plist->bv > 0) {
  443.             plist->bv = -drand48() / 16.0 - 0.01;
  444.         } else {
  445.             plist->bv = drand48() / 16.0 + 0.01;
  446.         }
  447.     }
  448.     if (Bound(0.0, &plist->point_list[plist->cur_point][2], 4.0)) {
  449.         if (plist->cv > 0) {
  450.             plist->cv = -drand48() / 16.0 - 0.01;
  451.         } else {
  452.             plist->cv = drand48() / 16.0 + 0.01;
  453.         }
  454.     }
  455.     if (Bound(0.0, &plist->point_list[plist->cur_point][3], 4.0)) {
  456.         if (plist->dv > 0) {
  457.             plist->dv = -drand48() / 16.0 - 0.01;
  458.         } else {
  459.             plist->dv = drand48() / 16.0 + 0.01;
  460.         }
  461.     }
  462.     Retina_SetAPen(rs, 0);
  463.     pl = plist->point_list[plist->last_point];
  464.     if (pl[0] >= 0.0)
  465.         Draw_Image(rs, pl[0], pl[1], pl[2], pl[3]);
  466.  
  467.     plist->last_point = (plist->last_point + 1) % LINE_BUF;
  468.  
  469. }
  470.  
  471. /*
  472.  * The Main Loop
  473.  */
  474.  
  475. void
  476. main(LONG argc, UBYTE * argv[])
  477. {
  478.     char **ToolTypes;
  479.     CxObj *Broker, *ObjectList, *Filter;
  480.     struct IntuiMessage *IntMsg;
  481.     CxMsg *BlankerCxMsg;
  482.     LONG ThisTimeOut, TimeUntilBlank, TimeUntilBlack;
  483.     struct RetinaScreen *BlankerScreen = NULL;
  484.     struct MsgPort *ClientPort = NULL;
  485.     int BlankFlag = 0;
  486.  
  487.     /*
  488.      * open our Libraries 
  489.      */
  490.     AddTool(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
  491.                                                37L), CloseLibrary, 0L,
  492.             "Couldn't open the intuition.library.");
  493.     AddTool(IconBase = OpenLibrary("icon.library", 37L), CloseLibrary, 0L,
  494.             "Couldn't open the icon library.");
  495.     AddTool(CxBase = OpenLibrary("commodities.library", 37L), CloseLibrary, 0L,
  496.             "Couldn't open the commoidities library.");
  497.     AddTool(GadToolsBase = OpenLibrary("gadtools.library", 37L), CloseLibrary, 0L,
  498.             "Couldn't open the gadtools library.");
  499.     AddTool(RetinaBase = (struct RetinaBase *)OpenLibrary("retina.library", 8L),
  500.             CloseLibrary, 0L, "Couldn't open the Retina library.");
  501.  
  502.     /*
  503.      * get our Arguments 
  504.      */
  505.  
  506.     if (ToolTypes = ArgArrayInit(argc, argv))
  507.         AddTool(ToolTypes, ArgArrayDone, 0L, NULL);
  508.  
  509.     /*
  510.      * get some Signals 
  511.      */
  512.  
  513.     ServerProcess = SysBase->ThisTask;
  514.     if ((bsp_TimerSig = AllocSignal(-1L)) == -1)
  515.         Quit(10, "Could not allocate a signal.");
  516.     AddTool((void *)bsp_TimerSig, FreeSignal, 0L, NULL);
  517.     if ((bsp_InputSig = AllocSignal(-1L)) == -1)
  518.         Quit(10, "Could not allocate a signal.");
  519.     AddTool((void *)bsp_InputSig, FreeSignal, 0L, NULL);
  520.     if ((bsp_ClientSig = AllocSignal(-1L)) == -1)
  521.         Quit(10, "Could not allocate a signal.");
  522.     AddTool((void *)bsp_ClientSig, FreeSignal, 0L, NULL);
  523.  
  524.     /*
  525.      * initialize our Broker = install us as a Commodity 
  526.      */
  527.  
  528.     AddTool(CxPort = CreateMsgPort(), DeleteMsgPortSafely, 0L,
  529.             "Failed to create a port.");
  530.  
  531.     VersionString[36]='\0';
  532.     NewBroker.nb_Title = &VersionString[11];
  533.     NewBroker.nb_Pri = ArgInt(ToolTypes, "CX_PRIORITY", DEF_CX_PRI);
  534.     NewBroker.nb_Port = CxPort;
  535.     AddTool(Broker = CxBroker(&NewBroker, NULL), DeleteCxObjAll, 0L,
  536.             NULL);
  537.  
  538.     /*
  539.      * get Time Out, Client Time Out and Display mode 
  540.      */
  541.  
  542.     TimeOut = ArgIntRange(ToolTypes, "TIMEOUT", 1L, DEF_TIMEOUT, MAX_TIMEOUT);
  543.     ClientTimeOut = ArgIntRange(ToolTypes, "CLIENTTIMEOUT", 1L, DEF_CLIENT_TIMEOUT,
  544.                                 MAX_CLIENT_TIMEOUT);
  545.  
  546.     /*
  547.      * get Parameters for Line Movement 
  548.      */
  549.  
  550.     NumLines = ArgIntRange(ToolTypes, "LINES", MIN_LINES, DEF_LINES, MAX_LINES);
  551.     Speed = ArgIntRange(ToolTypes, "SPEED", 1L, DEF_SPEED, MAX_SPEED);
  552.  
  553.     /*
  554.      * install our hot keys 
  555.      */
  556.  
  557.     PopKey = ArgString(ToolTypes, "CX_POPKEY", DEF_POPKEY);
  558.     BlankKey = ArgString(ToolTypes, "BLANKKEY", DEF_BLANKKEY);
  559.  
  560.     if ((Filter = HotKey(PopKey, CxPort, HOTKEY_OPEN_WINDOW)) == NULL)
  561.         Quit(10, "The CX_POPKEY tool type is invalid.");
  562.     else
  563.         AttachCxObj(Broker, Filter);
  564.     if (CxObjError(Filter))
  565.         Quit(10, "Could not link to the commodity list.");
  566.  
  567.     if ((Filter = HotKey(BlankKey, CxPort, HOTKEY_BLANK_SCREEN)) == NULL)
  568.         Quit(10, "The BLANKKEY tool type is invalid.");
  569.     else
  570.         AttachCxObj(Broker, Filter);
  571.     if (CxObjError(Filter))
  572.         Quit(10, "Could not link to the commodity list.");
  573.  
  574.     /*
  575.      * install our "InputHandler" 
  576.      */
  577.  
  578.     ObjectList = CxCustom(BlankerAction, 0L);
  579.     AttachCxObj(Broker, ObjectList);
  580.     if (CxObjError(ObjectList))
  581.         Quit(10, "Could not link to the commodity list.");
  582.  
  583.     (void)ActivateCxObj(Broker, TRUE);
  584.     AddTool(Broker, ActivateCxObj, 0L, "The broker broke.");
  585.  
  586.     /*
  587.      * open Window on startup if not forbidden 
  588.      */
  589.  
  590.     if (stricmp(ArgString(ToolTypes, "CX_POPUP", ""), "NO"))
  591.         OpenBlankerWindow();
  592.  
  593.     /*
  594.      * increase our Priority 
  595.      */
  596.  
  597.     AddTool(FindTask(NULL), SetTaskPri, (LONG) SetTaskPri(FindTask(NULL), SERVER_PRI),
  598.             "Findtask failed!");
  599.  
  600.     /*
  601.      * start the Loop 
  602.      */
  603.  
  604.     TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  605.     TimeUntilBlack = 10L * ClientTimeOut;
  606.  
  607.     FOREVER
  608.     {
  609.         ULONG Mask;
  610.  
  611.         if (BlankerWindow)
  612.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  613.                         MASK(CxPort->mp_SigBit) |
  614.                         MASK(BlankerWindow->UserPort->mp_SigBit) |
  615.                         SIGBREAKF_CTRL_C);
  616.         else
  617.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  618.                         MASK(CxPort->mp_SigBit) | SIGBREAKF_CTRL_C);
  619.  
  620.         /*
  621.          * process Window Events 
  622.          */
  623.  
  624.         while ((BlankerWindow != NULL) && (IntMsg =
  625.                                  GT_GetIMsg(BlankerWindow->UserPort)))
  626.             switch (IntMsg->Class) {
  627.                 struct Gadget *Clicked;
  628.                 UWORD Code;
  629.  
  630.             case IDCMP_CLOSEWINDOW:
  631.                 GT_ReplyIMsg(IntMsg);
  632.                 CloseBlankerWindow();
  633.                 break;
  634.             case IDCMP_REFRESHWINDOW:
  635.                 GT_BeginRefresh(BlankerWindow);
  636.                 GT_EndRefresh(BlankerWindow, TRUE);
  637.                 break;
  638.             case IDCMP_GADGETUP:
  639.                 Code = IntMsg->Code;
  640.                 Clicked = (struct Gadget *)IntMsg->IAddress;
  641.                 GT_ReplyIMsg(IntMsg);
  642.                 switch (Clicked->GadgetID) {
  643.                 case GID_HIDE:
  644.                     CloseBlankerWindow();
  645.                     break;
  646.                 case GID_QUIT:
  647.                     Quit(0, "Normal Termination.");
  648.                 case GID_BLANK:
  649.                     if (TimeUntilBlank)
  650.                         TimeUntilBlank = ThisTimeOut = 2L;
  651.                     break;
  652.                 case GID_TIMEOUT:
  653.                     if (GetNum(BlankerWindow, Clicked, 1L, &TimeOut, MAX_TIMEOUT))
  654.                         TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  655.                     break;
  656.                 case GID_CLIENT:
  657.                     if (GetNum(BlankerWindow, Clicked, 1L, &ClientTimeOut, MAX_CLIENT_TIMEOUT))
  658.                         TimeUntilBlack = 10L * ClientTimeOut;
  659.                     break;
  660.                 case GID_LINES:
  661.                     NumLines = Code;
  662.                     break;
  663.                 case GID_SPEED:
  664.                     Speed = Code;
  665.                     break;
  666.                 }
  667.                 break;
  668.             case IDCMP_VANILLAKEY:
  669.                 Code = IntMsg->Code;
  670.                 GT_ReplyIMsg(IntMsg);
  671.                 switch ((char)Code) {
  672.                 case 'H':
  673.                 case 'h':
  674.                     CloseBlankerWindow();
  675.                     break;
  676.                 case 'Q':
  677.                 case 'q':
  678.                     Quit(0, "Normal Termination.");
  679.                 case 'B':
  680.                 case 'b':
  681.                     if (TimeUntilBlank)
  682.                         TimeUntilBlank = ThisTimeOut = 2L;
  683.                 }
  684.                 break;
  685.             default:
  686.                 GT_ReplyIMsg(IntMsg);
  687.             }
  688.  
  689.         /*
  690.          * process Commodity Messages 
  691.          */
  692.  
  693.         while (BlankerCxMsg = (CxMsg *) GetMsg(CxPort))
  694.             HandleCxMsg(Broker, BlankerCxMsg, &TimeUntilBlank, &ThisTimeOut);
  695.  
  696.         /*
  697.          * check for <CTRL>-C 
  698.          */
  699.  
  700.         if (Mask & SIGBREAKF_CTRL_C)
  701.             Quit(0, "Normal Termination.");
  702.  
  703.         /*
  704.          * Input detected, unblank if necessary 
  705.          */
  706.  
  707.         if (Mask & MASK(bsp_InputSig)) {
  708.             if (BlankFlag) {
  709.                 if (ClientPort)
  710.                     RemTool(ClientPort);
  711.  
  712.                 if (BlankerScreen) {
  713.                     SpritesOn(BlankerScreen);
  714.                     RemTool(BlankerScreen);
  715.                 } else
  716.                     Retina_DisplayOn();
  717.                 BlankFlag = 0;
  718.                 ThisTimeOut = 10L * TimeOut;
  719.             }
  720.             TimeUntilBlank = ThisTimeOut;
  721.         }
  722.         /*
  723.          * client has confirmed that it is still alive 
  724.          */
  725.  
  726.         if (Mask & MASK(bsp_ClientSig)) {
  727.             if (BlankerScreen)
  728.                 Retina_DisplayOn();
  729.             TimeUntilBlack = 10L * ClientTimeOut;
  730.             BlankFlag = 1;
  731.         }
  732.         /*
  733.          * 1/10 sec is over 
  734.          */
  735.  
  736.         if (Mask & MASK(bsp_TimerSig))
  737.             if (TimeUntilBlank) {
  738.                 TimeUntilBlank--;
  739.                 if (TimeUntilBlank == 0L) {        /*
  740.                                                  * Time Out reached,
  741.                                                  * blank * the screen 
  742.                                                  */
  743.                     struct ClientMessage ClientMessage;
  744.  
  745.                     BlankFlag = 1;
  746.                     BlankerScreen = CreateScreen(color_table);
  747.                     if (BlankerScreen)
  748.                         AddTool(BlankerScreen, DestroyScreen, 0L, NULL);
  749.                     else
  750.                         /*
  751.                          * do this if we're completely out of video
  752.                          * memory. 
  753.                          */
  754.                         Retina_DisplayOff();
  755.  
  756.                     ClientMessage.bcm_Screen = BlankerScreen;
  757.                     ClientMessage.bcm_SigMask = 1L << bsp_ClientSig;
  758.                     ClientMessage.bcm_Lines = NumLines;
  759.                     ClientMessage.bcm_Speed = Speed;
  760.  
  761.                     if (ClientPort = CreateBlankerClient(RLinesClientProcess,
  762.                                                     &ClientMessage)) {
  763.                         TimeUntilBlack = 10L * ClientTimeOut;
  764.                         /*
  765.                          * try to start Client 
  766.                          */
  767.                         AddTool(ClientPort, DeleteBlankerClient, 0L, NULL);
  768.                     }
  769.                 }
  770.             } else {
  771.                 if ((BlankerScreen) && (RetinaBase->rb_FirstScreen != BlankerScreen)) {
  772.                     Retina_ScreenToFront(BlankerScreen);
  773.                     SpritesOff(BlankerScreen);
  774.                 }
  775.                 if (TimeUntilBlack) {
  776.                     TimeUntilBlack--;
  777.                     if (TimeUntilBlack == 0L)
  778.                         Retina_DisplayOff();    /*
  779.                                                  * Client Time Out *
  780.                                                  * reached, turn entire
  781.                                                  * * screen black 
  782.                                                  */
  783.                 }
  784.             }
  785.     }
  786. }
  787.